﻿using System;
using System.Threading;
using System.Windows.Forms;
using vkUpploaderLib.Resourses;

namespace vkUpploaderLib.HttpHelpers
{
    /// <summary>
    /// Used to create WebBrowser window and extract url from document
    /// </summary>
    internal class HrefExctractor : WebBrowserWindow
    {
        #region private fields

        private const string UrlPattern = "http://vkontakte.ru/photo{0}_{1}";
        private const string SrcDownnloadTag = "pvs_dd";

        /// <summary>
        /// тег "Отметить человека", если он есть, но нет другого тега - значит сворачиваемся
        /// </summary>
        private const string TagPeople = "pv_tag_link";

        private bool _isCompleted;
        private object _lockObject = new object();
        private DateTime _timeStampUpdated = DateTime.Now;

        private string _bigPictureUrl;

        public HrefExctractor(string userId, string photoId) : base(string.Format(UrlPattern, userId, photoId), StringResources.ProductName)
        {
            //call base ctor
        }

        #endregion

        /// <summary>
        /// Creates WebBrowser window and parse html document to extract src of big jpg link
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="photoId"></param>
        /// <returns></returns>
        public string GetOriginalUrl(string userId, string photoId)
        {
            try
            {
                NavigatedHandler += OnBrowserNavigatedEventHandler;
                CreateControls();
              
                _timeStampUpdated = DateTime.Now;

                // if browser hangs - UpdaterThread will force it to refresh 
                Thread thread = new Thread(SynchronizeThreadMethed);
                thread.Start(); 

                _form.ShowDialog();

                return _bigPictureUrl;
            }
            finally
            {
                DisposeControls();
            }
        }

        private void OnBrowserNavigatedEventHandler(object sender, WebBrowserNavigatedEventArgs e)
        {
            try
            {
                _timeStampUpdated = DateTime.Now;
                if (_webBrowser.Document != null)
                {
                    HtmlElement extractedTag = _webBrowser.Document.GetElementById(SrcDownnloadTag);
                    if (extractedTag != null)
                    {
                        lock (_lockObject)
                        {
                            _bigPictureUrl = GetLinkFromHtmlElement(extractedTag); ;
                            _isCompleted = true;
                            _form.Close();
                            return;
                        }
                    }
                    //If no bigger image 
                    else if (_webBrowser.Document.GetElementById(TagPeople) != null)
                    {
                        _isCompleted = true;
                        _form.Close();
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        private string GetLinkFromHtmlElement(HtmlElement extractedTag)
        {
            int pos1 = extractedTag.OuterHtml.IndexOf("href=\"");
            int pos2 = extractedTag.OuterHtml.IndexOf(".jpg\"", pos1);
            return extractedTag.OuterHtml.Substring(pos1 + "href=\"".Length, pos2 - pos1 - 2);
        }

        private void SynchronizeThreadMethed()
        {
            Thread.Sleep(2000);
            while (true)
            {
                if (_isCompleted)
                {
                    break;
                }
                if (DateTime.Now - new TimeSpan(0, 0, 5) > _timeStampUpdated)
                {
                    _timeStampUpdated = DateTime.Now;
                    if (Monitor.TryEnter(_lockObject))
                    {
                        try
                        {
                            _webBrowser.Invoke(new MethodInvoker(() => _webBrowser.Navigate(_url)));
                        }
                        finally
                        {
                            Monitor.Exit(_lockObject);
                        }
                    }
                }
                Thread.Sleep(100);
            }
        }
    }
}
